package com.zzyl.serve.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zzyl.common.annotation.DataSource;
import com.zzyl.common.enums.DataSourceType;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.serve.dto.SlotCountDTO;
import com.zzyl.serve.vo.ReservationCountVO;
import com.zzyl.serve.vo.TimeSlotVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.serve.mapper.ReservationMapper;
import com.zzyl.serve.domain.Reservation;
import com.zzyl.serve.service.IReservationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 预约信息Service业务层处理
 * 
 * @author yanbucai
 * @date 2025-05-09
 */
@Service
public class ReservationServiceImpl extends ServiceImpl<ReservationMapper, Reservation> implements IReservationService
{
    @Autowired
    private ReservationMapper reservationMapper;

    private static final int SLOT_INTERVAL = 150; // 分钟
    private static final int DAILY_LIMIT = 3;
    private static final int SLOT_CAPACITY = 6;

    /**
     * 查询预约信息
     * 
     * @param id 预约信息主键
     * @return 预约信息
     */
    @Override
    public Reservation selectReservationById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询预约信息列表
     * 
     * @param reservation 预约信息
     * @return 预约信息
     */
    @Override
    public List<Reservation> selectReservationList(Reservation reservation)
    {
        return reservationMapper.selectReservationList(reservation);
    }

    /**
     * 新增预约信息
     * 
     * @param reservation 预约信息
     * @return 结果
     */
    @Override
    public int insertReservation(Reservation reservation)
    {   reservation.setStatus(1);
        return save(reservation) ? 1 : 0;
    }

    /**
     * 修改预约信息
     * 
     * @param reservation 预约信息
     * @return 结果
     */
    @Override
    public int updateReservation(Reservation reservation)
    {
        return updateById(reservation) ? 1 : 0;
    }

    /**
     * 批量删除预约信息
     * 
     * @param ids 需要删除的预约信息主键
     * @return 结果
     */
    @Override
    public int deleteReservationByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除预约信息信息
     * 
     * @param id 预约信息主键
     * @return 结果
     */
    @Override
    public int deleteReservationById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    /**
     * @param countByTime
     * @return
     */
//    @Override
//    public Reservation selectReservationByCountByTime(LocalDateTime countByTime) {
//
//        return this.selectReservationByCountByTime(countByTime) ;
//    }


    /**
     * @param userId
     * @return
     */
    @Override
    @DataSource(DataSourceType.MASTER) // 若依多数据源支持
    public Integer getTodayCancelledCount(Long userId) {
        // 使用若依时间工具类
//        LocalDateTime beginTime = DateUtils.getTodayBeginTime();
//        LocalDateTime endTime = DateUtils.getTodayEndTime();
        long time = System.currentTimeMillis();
        LocalDateTime ldt = LocalDateTimeUtil.of(time);
        LocalDateTime startTime = ldt.toLocalDate().atStartOfDay();
        LocalDateTime endTime = startTime.plusDays(1);

        QueryWrapper<Reservation> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 2)
                .eq("update_by", userId)
                .between("update_time", startTime, endTime);
        Long l = reservationMapper.selectCount(wrapper);

        return Math.toIntExact(l);
    }




    @Override
    public List<TimeSlotVO> getTimeSlotInfo(LocalDateTime inputTime) {
        LocalDate date = inputTime.toLocalDate();

        // 生成当天所有有效时间段
        List<LocalDateTime> allSlots = generateTimeSlots(date);

        // 查询已预约数据
        LocalDateTime start = date.atStartOfDay();
        LocalDateTime end = date.plusDays(1).atStartOfDay().minusSeconds(1);

        List<SlotCountDTO> occupiedSlots = baseMapper.selectSlotCounts(start, end);
        Map<LocalDateTime, Integer> slotCountMap = occupiedSlots.stream()
                .collect(Collectors.toMap(SlotCountDTO::getSlotTime, SlotCountDTO::getCount));

        return allSlots.stream().map(slot -> {
            int booked = slotCountMap.getOrDefault(slot, 0);
            return new TimeSlotVO(
                    slot.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),
                    SLOT_CAPACITY - booked
            );
        }).collect(Collectors.toList());
    }

    private List<LocalDateTime> generateTimeSlots(LocalDate date) {
        List<LocalDateTime> slots = new ArrayList<>();
        LocalTime startTime = LocalTime.of(8, 0);
        LocalDateTime current = LocalDateTime.of(date, startTime);

        while (current.toLocalTime().isBefore(LocalTime.of(22, 0))) {
            slots.add(current);
            current = current.plusMinutes(SLOT_INTERVAL);
        }
        return slots;
    }
}
